package com.free4inno.knowledgems.controller;

import com.free4inno.knowledgems.constants.GroupConstants;
import com.free4inno.knowledgems.dao.SignupInfoDAO;
import com.free4inno.knowledgems.dao.UserDAO;
import com.free4inno.knowledgems.dao.UserGroupDAO;
import com.free4inno.knowledgems.domain.SignupInfo;
import com.free4inno.knowledgems.domain.User;
import com.free4inno.knowledgems.service.CleanResourceService;
import com.free4inno.knowledgems.service.UserService;
import com.free4inno.knowledgems.constants.UserConstants;
import com.free4inno.knowledgems.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

import java.sql.Timestamp;
import java.util.*;

/**
 * UserInfoController.
 */
@Slf4j
@Controller
@RequestMapping("/user")
public class UserInfoController {

    @Autowired
    private UserDAO userDao;

    @Autowired
    private UserGroupDAO userGroupDao;

    @Autowired
    private SignupInfoDAO signupInfoDao;

    @Autowired
    private CleanResourceService cleanResourceService;

    @Autowired
    private UserService userService;

//    @Value("${user.default.password}")
    private String userDefaultPswd;

    @RequestMapping("/userinfo")
    public String getUserInfo(Map param, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "获取用户信息(userInfo)" + "----" + session.getAttribute(UserConstants.USER_ID));
        if (session.getAttribute(GroupConstants.ROLE_ID).equals(1) || session.getAttribute(GroupConstants.ROLE_ID).equals(2)) {
            List<User> userInfos = userDao.findAll();
            int userNum = userDao.findAll().size();
            param.put(UserConstants.USER_NUM, userNum);
            param.put(UserConstants.USER_INFOS, userInfos);
            log.info(this.getClass().getName() + "----out----" + "用户有权限，返回用户信息页面" + "----" + session.getAttribute(UserConstants.USER_ID));
            return "user/userInfo";
        } else {
            log.info(this.getClass().getName() + "----out----" + "用户无权限" + "----" + session.getAttribute(UserConstants.USER_ID));
            return "redirect:/";
        }
    }

    @ResponseBody
    @PostMapping("/add")
    public Map<String, Object> newUser(@RequestParam String account,
                                       @RequestParam String realName,
                                       @RequestParam String mail,
                                       @RequestParam Integer roleId,
                                       HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "新增用户(add)" + "----" + session.getAttribute(UserConstants.USER_ID));
        Map<String, Object> jsonObject = new HashMap<>();

        List<User> users = userDao.findAll();

        int i = 0;

        for (User userCheck : users) {
            if (userCheck.getMail().equals(mail)) {
                i = i + 1;
            } else if (userCheck.getAccount().equals(account)) {
                i = i + 1;
            }
        }

        if (i == 0) {
            User user = new User();
            user.setAccount(account);
            user.setRealName(realName);
            user.setMail(mail);
            user.setRoleId(roleId);
            userDefaultPswd = userService.getDefaultPassword();
            user.setUserPassword(DigestUtils.md5DigestAsHex(userDefaultPswd.getBytes()));

            User saveUser = userDao.save(user);

            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, saveUser);
            jsonObject.put(UserConstants.DEFAULT_PASSWORD, userDefaultPswd);
            log.info(this.getClass().getName() + "----out----" + "添加成功" + "----" + session.getAttribute(UserConstants.USER_ID));
        } else {
            jsonObject.put(UserConstants.CODE, 500);
            log.info(this.getClass().getName() + "----out----" + "添加失败" + "----" + session.getAttribute(UserConstants.USER_ID));
        }

        return jsonObject;
    }

    @ResponseBody
    @PatchMapping("/modify/{id}")
    public Map<String, Object> updateLabel(@RequestParam String account,
                                           @RequestParam String realName,
                                           @RequestParam String mail,
                                           @RequestParam int roleId,
                                           @PathVariable int id, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "修改用户信息(modify)" + "----" + session.getAttribute(UserConstants.USER_ID));

        Map<String, Object> jsonObject = new HashMap<>();

        List<User> users = userDao.findAll();

        int i = 0;

        for (User userCheck : users) {
            if (!(userCheck.getId() == id)) {
                if (userCheck.getMail().equals(mail)) {
                    i = i + 1;
                } else if (userCheck.getAccount().equals(account)) {
                    i = i + 1;
                }
            }
        }

        if (i == 0) {
            User user = userDao.findById(id).orElseThrow(() -> new UserNotFoundException(id, session));
            user.setAccount(account);
            user.setMail(mail);
            user.setRoleId(roleId);
            user.setRealName(realName);
            user.setMail(mail);
            // user.setUserPassword(DigestUtils.md5DigestAsHex(userDefaultPswd.getBytes()));

            User updateUser = userDao.save(user);
            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, updateUser);
            // jsonObject.put("defaultPassword", userDefaultPswd);
            log.info(this.getClass().getName() + "----out----" + "修改成功，返回修改后的用户信息" + "----" + session.getAttribute(UserConstants.USER_ID));
        } else {
            jsonObject.put(UserConstants.CODE, 500);
            log.info(this.getClass().getName() + "----out----" + "修改失败，没有找到对应用户" + "----" + session.getAttribute(UserConstants.USER_ID));
        }
        return jsonObject;
    }

    @ResponseBody
    @PostMapping("/resetAppKey")
    public Map<String, Object> resetAppKey(@RequestParam(value = "userId", required = true) int userId,
                                           HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "分配用户appKey" + "----" + session.getAttribute(UserConstants.USER_ID));
        Map<String, Object> jsonObject = new HashMap<>();
        try {
            log.info(this.getClass().getName() + "----" + "待分配用户:" + userId + "----" + session.getAttribute(UserConstants.USER_ID));
            // 1. 生成appKey
            String newAppKey = StringUtils.getRandomString(8);
            // 2. 查重确认
            while (userDao.findAllByAppKey(newAppKey).isPresent()){
                newAppKey = StringUtils.getRandomString(8);
            }
            // 3. 保存新appKey
            User user = userDao.findById(userId).orElseThrow(() -> new UserNotFoundException(userId, session));
            user.setAppKey(newAppKey);
            User updateUser = userDao.save(user);
            // 4. 构建返回
            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, updateUser);
            log.info(this.getClass().getName() + "----out----" + "分配成功" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        } catch (Exception e) {
            jsonObject.put(UserConstants.CODE, 500);
            jsonObject.put(UserConstants.MSG, e.getMessage());
            jsonObject.put(UserConstants.RESULT, null);
            log.info(this.getClass().getName() + "----out----" + "分配失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        }
    }

    @ResponseBody
    @PatchMapping("/resetPassword/{resetId}")
    public Map<String, Object> resetPassword(@PathVariable int resetId,
                                             HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "重置密码(resetPassword)" + "----" + session.getAttribute(UserConstants.USER_ID));

        Map<String, Object> jsonObject = new HashMap<>();

        try {
            log.info(this.getClass().getName() + "----" + "重置用户:" + resetId + "----" + session.getAttribute(UserConstants.USER_ID));
            User user = userDao.findById(resetId).orElseThrow(() -> new UserNotFoundException(resetId, session));

            userDefaultPswd = userService.getDefaultPassword();
            user.setUserPassword(DigestUtils.md5DigestAsHex(userDefaultPswd.getBytes()));
            User updateUser = userDao.save(user);

            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, updateUser);
            jsonObject.put(UserConstants.DEFAULT_PASSWORD, userDefaultPswd);
            log.info(this.getClass().getName() + "----out----" + "重置成功" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        } catch (LabelInfoController.LabelNotFoundException e) {
            jsonObject.put(UserConstants.CODE, 500);
            jsonObject.put(UserConstants.MSG, e.getMessage());
            jsonObject.put(UserConstants.RESULT, null);
            log.info(this.getClass().getName() + "----out----" + "重置失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        }
    }

    @ResponseBody
    @PatchMapping("/changePassword")
    public Map<String, Object> changePassword(@RequestParam String psd,
                                              @RequestParam String oldPsd,
                                              @RequestParam Integer changeId,
                                              HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "修改密码(changePassword)" + "----" + session.getAttribute(UserConstants.USER_ID));

        Map<String, Object> jsonObject = new HashMap<>();

        try {
            log.info(this.getClass().getName() + "----" + "修改用户:" + changeId + "----" + session.getAttribute(UserConstants.USER_ID));
            User user = userDao.findById(changeId).orElseThrow(() -> new UserNotFoundException(changeId, session));
            if (oldPsd.equals(user.getUserPassword())) {
                user.setUserPassword(psd);
                User updateUser = userDao.save(user);
                jsonObject.put(UserConstants.CODE, 200);
                jsonObject.put(UserConstants.MSG, "OK");
                jsonObject.put(UserConstants.RESULT, updateUser);
                log.info(this.getClass().getName() + "----out----" + "修改成功" + "----" + session.getAttribute(UserConstants.USER_ID));
            } else {
                jsonObject.put(UserConstants.CODE, 500);
                log.info(this.getClass().getName() + "----out----" + "修改失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            }
            return jsonObject;
        } catch (LabelInfoController.LabelNotFoundException e) {
            log.info(this.getClass().getName() + "----out----" + "修改失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            jsonObject.put(UserConstants.CODE, 500);
            jsonObject.put(UserConstants.MSG, e.getMessage());
            jsonObject.put(UserConstants.RESULT, null);
            return jsonObject;
        }
    }

    @ResponseBody
    @GetMapping("/getEmail")
    public String getEmail(HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "(getEmail)" + "----" + session.getAttribute(UserConstants.USER_ID));
        String mail = "";
        List<User> users = userDao.findAll();
        for (User user : users) {
            if (user.getRoleId() == 2) {
                mail = user.getMail();
                break;
            }
        }
        log.info(this.getClass().getName() + "----out----" + "返回获取到的邮箱" + "----" + session.getAttribute(UserConstants.USER_ID));
        return mail;
    }

    @ResponseBody
    @PatchMapping("/applyToNo/{applyId}")
    public Map<String, Object> applyToNo(@PathVariable int applyId, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "(applyToNo)" + "----" + session.getAttribute(UserConstants.USER_ID));

        Map<String, Object> jsonObject = new HashMap<>();

        try {
            SignupInfo signupInfo = signupInfoDao.findById(applyId).orElseThrow(() -> new UserNotFoundException(applyId, session));
            signupInfo.setStatus(2);
            signupInfo.setProcessTime(new Timestamp(new Date().getTime()));
            SignupInfo updateApply = signupInfoDao.save(signupInfo);

            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, updateApply);
            log.info(this.getClass().getName() + "----out----" + "成功，返回updateApply" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        } catch (LabelInfoController.LabelNotFoundException e) {
            jsonObject.put(UserConstants.CODE, 500);
            jsonObject.put(UserConstants.MSG, e.getMessage());
            jsonObject.put(UserConstants.RESULT, null);
            log.info(this.getClass().getName() + "----out----" + "失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        }
    }

    @ResponseBody
    @PatchMapping("/deleteApply/{applyId}")
    public Map<String, Object> deleteApply(@PathVariable int applyId, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "(deleteApply)" + "----" + session.getAttribute(UserConstants.USER_ID));

        Map<String, Object> jsonObject = new HashMap<>();

        try {
            SignupInfo signupInfo = signupInfoDao.findById(applyId).orElseThrow(() -> new UserNotFoundException(applyId, session));
            signupInfo.setStatus(3);
            signupInfo.setProcessTime(new Timestamp(new Date().getTime()));
            SignupInfo updateApply = signupInfoDao.save(signupInfo);

            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, updateApply);
            log.info(this.getClass().getName() + "----out----" + "成功，已删除apply" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        } catch (LabelInfoController.LabelNotFoundException e) {
            jsonObject.put(UserConstants.CODE, 500);
            jsonObject.put(UserConstants.MSG, e.getMessage());
            jsonObject.put(UserConstants.RESULT, null);
            log.info(this.getClass().getName() + "----out----" + "失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        }
    }

    @ResponseBody
    @PatchMapping("/applyToUser/{applyId}")
    public Map<String, Object> applyToUser(@PathVariable int applyId, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "(applyToUser)" + "----" + session.getAttribute(UserConstants.USER_ID));

        Map<String, Object> jsonObject = new HashMap<>();

        try {
            SignupInfo signupInfo = signupInfoDao.findById(applyId).orElseThrow(() -> new UserNotFoundException(applyId, session));
            signupInfo.setStatus(1);
            signupInfo.setProcessTime(new Timestamp(new Date().getTime()));
            SignupInfo updateApply = signupInfoDao.save(signupInfo);

            User user = new User();
            user.setAccount(signupInfo.getTelnumber());
            user.setRealName(signupInfo.getName());
            user.setMail(signupInfo.getMail());
            user.setRoleId(0);
            userDefaultPswd = userService.getDefaultPassword();
            user.setUserPassword(DigestUtils.md5DigestAsHex(userDefaultPswd.getBytes()));
            User updateUser = userDao.save(user);

            jsonObject.put(UserConstants.CODE, 200);
            jsonObject.put(UserConstants.MSG, "OK");
            jsonObject.put(UserConstants.RESULT, updateApply);
            jsonObject.put("new", updateUser);
            jsonObject.put(UserConstants.DEFAULT_PASSWORD, userDefaultPswd);
            log.info(this.getClass().getName() + "----out----" + "成功, apply新的user" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        } catch (LabelInfoController.LabelNotFoundException e) {
            jsonObject.put(UserConstants.CODE, 500);
            jsonObject.put(UserConstants.MSG, e.getMessage());
            jsonObject.put(UserConstants.RESULT, null);
            log.info(this.getClass().getName() + "----out----" + "失败" + "----" + session.getAttribute(UserConstants.USER_ID));
            return jsonObject;
        }
    }

    @ResponseBody
    @PostMapping("/getRoles")
    public List<String> getRoles(HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "获取角色列表(getRoles)" + "----" + session.getAttribute(UserConstants.USER_ID));

        List<String> roleList = new ArrayList<>();

        roleList.add(UserConstants.AVERAGE_USER);
        roleList.add(UserConstants.USER_ADMINISTRATOR);
        roleList.add(UserConstants.CONTENT_ADMINISTRATOR);
        roleList.add(UserConstants.SYSTEM_ADMINISTRATOR);

        log.info(this.getClass().getName() + "----out----" + "返回获取到的角色列表" + "----" + session.getAttribute(UserConstants.USER_ID));
        return roleList;
    }

    @ResponseBody
    @DeleteMapping("/{id}")
    public Map<String, Object> deleteLabel(@PathVariable int id, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "(deleteLabel)" + "----" + session.getAttribute(UserConstants.USER_ID));
        Map<String, Object> jsonObject = new HashMap<>();
        userDao.deleteById(id);
        userGroupDao.deleteAllByUserId(id);
        cleanResourceService.cleanUserIdInResource(id);
        jsonObject.put(UserConstants.CODE, 200);
        jsonObject.put(UserConstants.MSG, "OK");
        jsonObject.put(UserConstants.RESULT, null);
        log.info(this.getClass().getName() + "----out----" + "已删除用户:" + id + "----" + session.getAttribute(UserConstants.USER_ID));
        return jsonObject;
    }

    @RequestMapping("/userManagement")
    public String getAllUsers(Map param, HttpSession session,
                              @RequestParam("page") int currentPage,
                              @RequestParam("search") String searchKey) {
        log.info(this.getClass().getName() + "----in----" + "(userManagement)" + "----" + session.getAttribute(UserConstants.USER_ID));

        int maxItems = 12;
        int pageNum = 0;
        int searchedUserNum = 0;
        List<User> userInfos = new ArrayList<>();

        // judge search
        if (searchKey.isEmpty()){
            // no search and query all through page
            Sort sort = Sort.by(Sort.Direction.ASC, "roleId");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            Page<User> usersPage = userDao.findAllByRoleId(0, pageable);
            // get content and page number
            pageNum = usersPage.getTotalPages();
            userInfos = usersPage.getContent();
        } else {
            // have search and query by searchKey
            searchKey = "%" + searchKey + "%";
            Sort sort = Sort.by(Sort.Direction.ASC, "roleId");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            // here is a long query in order to search key in "account","name","mail". AND roleId must be 0.
            Page<User> usersPage = userDao.findAllByRoleIdAndAccountLikeOrRoleIdAndRealNameLikeOrRoleIdAndMailLike(
                    0, searchKey, 0, searchKey, 0, searchKey, pageable);
            // get content and page number
            pageNum = usersPage.getTotalPages();
            userInfos = usersPage.getContent();
            searchedUserNum = (int)usersPage.getTotalElements();
        }

        // users only, dont need to sort

        // count number for tab bar
        int userNum = userDao.countAllByRoleId(0);
        int managerNum = userDao.countAllByRoleIdIsNot(0);
        int applyNum = signupInfoDao.countAllByStatus(0);
        int refuseNum = signupInfoDao.countAllByStatus(2);

        // list and page
        param.put(UserConstants.USER_LIST, userInfos);
        param.put(UserConstants.SEARCH_USERNUM, searchedUserNum);
        param.put(UserConstants.MAXPAGES, pageNum);
        param.put(UserConstants.CURRENT_PAGE, currentPage);
        // show count number
        param.put(UserConstants.USER_NUM, userNum);
        param.put(UserConstants.MANAGER_NUM, managerNum);
        param.put(UserConstants.APPLY_NUM, applyNum);
        param.put(UserConstants.REFUSE_NUM, refuseNum);

        log.info(this.getClass().getName() + "----out----" + "返回用户列表" + "----" + session.getAttribute(UserConstants.USER_ID));
        return "user/_userList";
    }

    @RequestMapping("/userManagerManagement")
    public String getAllManagers(Map param, HttpSession session,
                                 @RequestParam("page") int currentPage,
                                 @RequestParam("search") String searchKey) {
        log.info(this.getClass().getName() + "----in----" + "(userManagerManagement)" + "----" + session.getAttribute(UserConstants.USER_ID));

        int maxItems = 12;
        int pageNum = 0;
        int searchedUserNum = 0;
        List<User> userInfos = new ArrayList<>();

        // judge search
        if (searchKey.isEmpty()){
            // no search and query all through page
            Sort sort = Sort.by(Sort.Direction.ASC, "roleId");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            Page<User> usersPage = userDao.findAllByRoleIdIsNot(0, pageable);
            // get content and page number
            pageNum = usersPage.getTotalPages();
            userInfos = usersPage.getContent();
        } else {
            // have search and query by searchKey
            searchKey = "%" + searchKey + "%";
            Sort sort = Sort.by(Sort.Direction.ASC, "roleId");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            // here is a long query in order to search key in "account","name","mail". AND roleId must NOT be 0.
            Page<User> usersPage = userDao.findAllByRoleIdIsNotAndAccountLikeOrRoleIdIsNotAndRealNameLikeOrRoleIdIsNotAndMailLike(
                    0, searchKey, 0, searchKey, 0, searchKey, pageable);
            // get content and page number
            pageNum = usersPage.getTotalPages();
            userInfos = usersPage.getContent();
            searchedUserNum = (int)usersPage.getTotalElements();
        }

        // managers is sorted by using JPA's pageable

        // count number for tab bar
        int userNum = userDao.countAllByRoleId(0);
        int managerNum = userDao.countAllByRoleIdIsNot(0);
        int applyNum = signupInfoDao.countAllByStatus(0);
        int refuseNum = signupInfoDao.countAllByStatus(2);

        // list and page
        param.put(UserConstants.USER_LIST, userInfos);
        param.put(UserConstants.SEARCH_USERNUM, searchedUserNum);
        param.put(UserConstants.MAXPAGES, pageNum);
        param.put(UserConstants.CURRENT_PAGE, currentPage);
        // show count number
        param.put(UserConstants.USER_NUM, userNum);
        param.put(UserConstants.MANAGER_NUM, managerNum);
        param.put(UserConstants.APPLY_NUM, applyNum);
        param.put(UserConstants.REFUSE_NUM, refuseNum);

        log.info(this.getClass().getName() + "----out----" + "返回用户管理表" + "----" + session.getAttribute(UserConstants.USER_ID));
        return "user/_managerList";
    }

    @RequestMapping("/userApplyManagement")
    public String getApplyUsers(Map param, HttpSession session,
                                @RequestParam("page") int currentPage,
                                @RequestParam("search") String searchKey) {
        log.info(this.getClass().getName() + "----in----" + "(userApplyManagement)" + "----" + session.getAttribute(UserConstants.USER_ID));

        int maxItems = 12;
        int pageNum = 0;
        int searchedApplyNum = 0;
        List<SignupInfo> applyList = new ArrayList<>();

        // judge search
        if (searchKey.isEmpty()){
            // no search and query all through page
            Sort sort = Sort.by(Sort.Direction.DESC, "signupTime");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            Page<SignupInfo> applyPage = signupInfoDao.findAllByStatus(0, pageable);
            // get content and page number
            pageNum = applyPage.getTotalPages();
            applyList = applyPage.getContent();
        } else {
            // have search and query by searchKey
            searchKey = "%" + searchKey + "%";
            Sort sort = Sort.by(Sort.Direction.DESC, "signupTime");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            // here is a long query in order to search key in "name","tel","mail". AND status must be 0.
            Page<SignupInfo> applyPage = signupInfoDao.findAllByStatusAndNameLikeOrStatusAndTelnumberLikeOrStatusAndMailLike(
                    0, searchKey, 0, searchKey, 0, searchKey, pageable);
            // get content and page number
            pageNum = applyPage.getTotalPages();
            applyList = applyPage.getContent();
            searchedApplyNum = (int)applyPage.getTotalElements();
        }

        // count number for tab bar
        int userNum = userDao.countAllByRoleId(0);
        int managerNum = userDao.countAllByRoleIdIsNot(0);
        int applyNum = signupInfoDao.countAllByStatus(0);
        int refuseNum = signupInfoDao.countAllByStatus(2);

        // list page
        param.put(UserConstants.APPLY_LIST, applyList);
        param.put(UserConstants.SEARCHED_APPLY_NUM, searchedApplyNum);
        param.put(UserConstants.MAXPAGES, pageNum);
        param.put(UserConstants.CURRENT_PAGE, currentPage);
        // count number
        param.put(UserConstants.USER_NUM, userNum);
        param.put(UserConstants.MANAGER_NUM, managerNum);
        param.put(UserConstants.APPLY_NUM, applyNum);
        param.put(UserConstants.REFUSE_NUM, refuseNum);

        log.info(this.getClass().getName() + "----out----" + "返回用户申请表" + "----" + session.getAttribute(UserConstants.USER_ID));
        return "user/_applyList";
    }

    @RequestMapping("/userRefuseManagement")
    public String getRefuseUsers(Map param, HttpSession session,
                                 @RequestParam("page") int currentPage,
                                 @RequestParam("search") String searchKey) {
        log.info(this.getClass().getName() + "----in----" + "(userRefuseManagement)" + "----" + session.getAttribute(UserConstants.USER_ID));

        int maxItems = 12;
        int pageNum = 0;
        int searchedRefuseNum = 0;
        List<SignupInfo> refuseList = new ArrayList<>();

        // judge search
        if (searchKey.isEmpty()){
            // no search and query all through page
            Sort sort = Sort.by(Sort.Direction.DESC, "processTime");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            Page<SignupInfo> refusePage = signupInfoDao.findAllByStatus(2, pageable);
            // get content and page number
            pageNum = refusePage.getTotalPages();
            refuseList = refusePage.getContent();
        } else {
            // have search and query by searchKey
            searchKey = "%" + searchKey + "%";
            Sort sort = Sort.by(Sort.Direction.DESC, "processTime");
            Pageable pageable = PageRequest.of(currentPage - 1, maxItems, sort);
            // here is a long query in order to search key in "name","tel","mail". AND status must be 2.
            Page<SignupInfo> refusePage = signupInfoDao.findAllByStatusAndNameLikeOrStatusAndTelnumberLikeOrStatusAndMailLike(
                    2, searchKey, 2, searchKey, 2, searchKey, pageable);
            // get content and page number
            pageNum = refusePage.getTotalPages();
            refuseList = refusePage.getContent();
            searchedRefuseNum = (int)refusePage.getTotalElements();
        }

        // count number for tab bar
        int userNum = userDao.countAllByRoleId(0);
        int managerNum = userDao.countAllByRoleIdIsNot(0);
        int applyNum = signupInfoDao.countAllByStatus(0);
        int refuseNum = signupInfoDao.countAllByStatus(2);

        // list page
        param.put(UserConstants.APPLY_LIST, refuseList);
        param.put(UserConstants.SEARCHED_APPLY_NUM, searchedRefuseNum);
        param.put(UserConstants.MAXPAGES, pageNum);
        param.put(UserConstants.CURRENT_PAGE, currentPage);
        // count number
        param.put(UserConstants.USER_NUM, userNum);
        param.put(UserConstants.MANAGER_NUM, managerNum);
        param.put(UserConstants.APPLY_NUM, applyNum);
        param.put(UserConstants.REFUSE_NUM, refuseNum);

        log.info(this.getClass().getName() + "----out----" + "返回用户申请拒绝表" + "----" + session.getAttribute(UserConstants.USER_ID));
        return "user/_refuseList";
    }

    static class UserNotFoundException extends RuntimeException {
        UserNotFoundException(Integer id, HttpSession session) {
            super(UserConstants.NO_USERINFO + id);
            log.error(this.getClass().getName()+"----"+"find user info by id"+"----failure----"+"Not found user info " + id +"----"+session.getAttribute(UserConstants.USER_ID));
        }
    }
}
